# 使用read_csv读取数据3.csv
import pandas as pd
import numpy as np
from pyecharts import options as opts
from pyecharts.charts import Bar, Timeline
from pyecharts.globals import ThemeType
from pyecharts.charts import Scatter
from pyecharts.charts import Line
from pyecharts.charts import Boxplot
from pyecharts.charts import Scatter3D
from pyecharts.charts import Pie
from pyecharts.charts import Timeline
data=pd.read_csv('D:/数据可视化/实验5/数据3.csv',sep=";",encoding='utf-8')
# print('2017无人数售货机数据: ',len(data))
data.head(3)

# 按照商品分类计数，计算销量前5的商品
data1=data.groupby('商品').size()
# print(data.head(5))#排序前
data1=data1.sort_values(ascending=False)#从小到大倒序
data2=data1.head(5)#排序后取销量前5名
# print(data2)

# 绘制销量前5的商品销量柱形图
init_opts=opts.InitOpts(width='1000px',height='450px',theme=ThemeType.LIGHT)
bar=(
   Bar(init_opts)
   .add_xaxis(data2.index.tolist())
   .add_yaxis('销售量',data2.values.tolist())
   .set_global_opts(
      title_opts=opts.TitleOpts(title='销量前5的商品销量柱形图',subtitle=' '),
      xaxis_opts=opts.AxisOpts( splitline_opts=opts.SplitLineOpts(is_show=True),
         name='商品'),
      yaxis_opts=opts.AxisOpts(name='销售量',
            type_='value',
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True),
     ),
       tooltip_opts=opts.TooltipOpts(is_show=True),
   )
   .set_series_opts(label_opts=opts.LabelOpts(is_show=True),
        )
)
bar.render('1.html')

# 排除非法的日期数据
data3=data
ind1=(data3['支付时间'] == '2017/2/29  15:44:00')
data3=data3.loc[~ind1,: ]
data3['支付时间']=pd.to_datetime(data3['支付时间'])
data3['月份']=data3['支付时间'].dt.month
# print(data3.tail(5))

# 对每台销货机按照月份分组，汇总交易额
data3_group=data3['实际金额'].groupby([data3['设备ID'], data3['月份']]).sum()
data3_group
#准备绘图数据
设备=[ ]
月份=[k for k in range(1,13) ]#12个月
num=int(len(data3_group.values)/12)#计算有多少台设备
实际金额=data3_group.values.reshape(num,12)

for k in range(num):
    x=data3_group.index[k*12][0]#取设备ID名称
    设备.append(x)

# print('设备ID:',设备)
# print('月份:',月份)
# print('实际金额:\n',实际金额)

# 所有折现统一在set_global_opts()中定义
line=Line()
line.add_xaxis(月份)

#添加不同设备的折线
for k in range(len(设备)):
    devices=设备[k]
    line.add_yaxis(devices,实际金额[k],is_smooth=True)#设置曲线光滑

#设置全局选项
line.set_global_opts(title_opts=opts.TitleOpts(title='每台销货机每月的总交易额曲线图'),
                    xaxis_opts=opts.AxisOpts(splitline_opts=opts.SplitLineOpts(is_show=True),name='月份'),
                    yaxis_opts=opts.AxisOpts(name='销售额',
                        type_='value',
                        axistick_opts=opts.AxisTickOpts(is_show=True) ),
                    legend_opts=opts.LegendOpts( pos_top='40',is_show=True)
                    )
#设置系列配置项
line.set_series_opts(linestyle_opts=opts.LineStyleOpts(width=5.0,opacity=0.5,type_='solid'),#设置折线
                    label_opts=opts.LabelOpts(is_show=False))#折线上部是否显示销售额数据

line.render('2.html')

# 对每台销货机按照月份分组，汇总交易金额
data4_group=data3['实际金额'].groupby([data3['设备ID'],data3['大类']]).sum()
# print(data4_group)

# 准备绘图数据
设备 = []
大类名称 = []
num = int(len(data4_group.values) / 2)  # 计算有多少台设备
实际金额 = data4_group.values.reshape(num, 2)
for k in range(num):
    x = data4_group.index[k * 2][0]  # 取设备ID名称
    设备.append(x)

for k in range(2):
    大类名称.append(data4_group.index[k][1])

print("设备ID:", 设备)
print("大类名称:", 大类名称)
print("实际金额:\n", 实际金额)

# 对各个售货机按照大类绘制销售额饼图
# for k in range(num):#num为销货机的数量
#     title=设备[k]+'售货机各类(按大类)商品的销售额饼图'
#     html="D:/数据可视化/实验5/"+title+".html"
#     pie=(Pie()
#         .add('',  [list(z) for z in zip(大类名称,实际金额[k])])
#         .set_global_opts(title_opts=opts.TitleOpts(title=title),
#                         legend_opts=opts.LegendOpts( pos_top='40',is_show=True))
#         .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} ({d}%)'))
#     )
#     pie.render(html)#每一台售货机按照大类生成一个销售额饼图，保存在html文件中
# pie.render('3.html')

# 使用read_csv读取数据3.csv
import pandas as pd
import numpy as np
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType
from pyecharts.charts import Scatter
from pyecharts.charts import Line
from pyecharts.charts import Boxplot
from pyecharts.charts import Scatter3D
from pyecharts.charts import Pie
from pyecharts.charts import Timeline
data=pd.read_csv('D:/数据可视化/实验5/数据3.csv',sep=";",encoding='utf-8')
# print('2017无人数售货机数据: ',len(data))
# print(data.head(3))

# 排除非法的日期数据
data3=data
ind1=(data3['支付时间'] == '2017/2/29  15:44:00')

data3=data3.loc[~ind1,: ]
data3['支付时间']=pd.to_datetime(data3['支付时间'])#转换日期时间格式
data3['月份']=data3['支付时间'].dt.month
# print(data3.tail(5))

# 对每台销货机按照月份分组，汇总其交易额
data3_group=data3['实际金额'].groupby([data3['设备ID'],data3['月份']]).sum()
# print(data3_group)

# 准备绘图数据 核心数据是第j月k台设备的销售金额：月份_设备_金额[j][k]二位列表
设备 = []
月份 = [k for k in range(1, 13)]  # 12个月
num = int(len(data3_group.values) / 12)  # 计算有多少台设备
实际金额 = data3_group.values.reshape(num, 12)
for k in range(num):
    x = data3_group.index[k * 12][0]  # 取设备ID名称
    设备.append(x)

# print('设备ID:', 设备)
# print('月份:', 月份)
# print('实际金额:\n',实际金额)

data33_group = data3['实际金额'].groupby([data3['月份'], data3['设备ID']]).sum()
# 各月每台设备的销售金额
月份_设备_金额 = data33_group.values.reshape(12, num)

# 转换为2维数据 第一维为月份，第二维维设备号
# 月份_设备_金额[j][k]其数值为j月份，k设备的销售金额
# print('月份_设备_金额:\n', 月份_设备_金额)


# 绘制时间线轮播图
time=月份
x_data=设备
timeline=Timeline()
for i in range(len(time)):
    y_data=月份_设备_金额[i]
    y_data=[str(j) for j in y_data]
    bar=(Bar()
        .add_xaxis(x_data)
        .add_yaxis('销售金额',y_data)
        .set_global_opts(title_opts=opts.TitleOpts(f'2017年{i+1}月每台销货机的销售额时间线轮播图'))
        )
    timeline.add(bar,time[i])#添加bar到时间线
timeline.add_schema(play_interval=1000,is_auto_play=True,symbol='pin')#添加轮播方案
timeline.render('3.html')

# 对每台销货机按照月份分组，汇总其交易金额
data4_group=data3['实际金额'].groupby([data3['设备ID'],data3['大类']]).sum()
# print(data4_group)

# 准备绘图数据
设备 = [ ]
大类名称=[ ]
num=int(len(data4_group.values)/2)#计算有多少台设备
实际金额=data4_group.values.reshape(num,2)
for k in range(num):
    x=data4_group.index[k*2][0]
    设备.append(x)
for k in range(2):
    大类名称.append(data4_group.index[k][1])

# print('设备ID:',设备)
# print('大类名称:',大类名称)
# print('实际金额:',实际金额)

# 对面各个售货机按照大类绘制销售额饼图
for k in range(num):
 title=设备[k]+'售货机各类(按大类商品的销售额饼图)'#标题名称
 html='D:/数据可视化/实验5/'+title+'.html'
 pie=(Pie()
    .add('',   [list(z) for z in zip(大类名称,实际金额[k])])
    .set_global_opts(title_opts=opts.TitleOpts(title=title),
                    legend_opts=opts.LegendOpts(pos_top='40',is_show=True))
    .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} ({d}%)'))
    )
 pie.render(html)#每一台售货机按照大类生成一个销售额饼图，保存在html文件中
pie.render_notebook()

from pyecharts.charts import Bar,Pie,Grid
from pyecharts import options as opts
import pandas as pd
from pyecharts.charts import Page
from pyecharts.globals import ThemeType
pie_name=[]
for k in range(num):
    pie_n='pie_'+str(k)
    pie_name.append(pie_n)
    title=设备[k]+'售货机各类(按大类)商品的销售额饼图'
    html='../tmp/'+title+'.html'
    pie_name[k]=(Pie(init_opts=opts.InitOpts(width='600px',height='310px'))
                .add('',  [list(z) for z in zip(大类名称,实际金额[k])])
                .set_global_opts(title_opts=opts.TitleOpts(title=title),
                                legend_opts=opts.LegendOpts( orient='vertical',pos_left=0,pos_bottom='40%',is_show=True))
                .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} ({d}%)'))
                )
page=(Page(page_title='Page绘制顺序多图',interval=3,#表示每个图例之间的间隔
          layout=Page.DraggablePageLayout).add(pie_name[0],pie_name[1],pie_name[2],pie_name[3],pie_name[4]))
page.render('4.html')

# 观察data3_group的结构
# print(data3_group)

# 按照设备-大类-月份 分组
data5_group=data3['实际金额'].groupby([data3['设备ID'],data3['大类'],data3['月份']]).sum()
# print(data5_group.head(30))

# 生成第i台设备第j大类各月的销售额数据
设备_大类_月份_金额=data5_group.values.reshape(5,2,12)
# print(设备_大类_月份_金额)

# 生成绘图所需要的数据
y_data_1=设备_大类_月份_金额[0] [0]
y_data_2=设备_大类_月份_金额[0] [1]
y_data_1=[str(j) for j in y_data_1]
y_data_2=[str(j) for j in y_data_2]

bar_0=(Bar()
      .add_xaxis([1,2,3,4,5,6,7,8,9,10,11,12])
      .add_yaxis('非饮料',y_data_1)
      .add_yaxis('饮料',y_data_2)
      .set_global_opts(title_opts=opts.TitleOpts(f'{设备[0]}-2017年各月（按大类）商品的销售额图'),
                      legend_opts=opts.LegendOpts(orient='vertical',pos_top=30,pos_bottom='40%',is_show=True)
                      )
      )
bar_0.render('5.html')

# # 非饮料各月数据
# print(设备_大类_月份_金额[0] [0])#设备0非饮料各月数据
#
# #饮料各月数据
# print(设备_大类_月份_金额[0] [1])#设备0饮料各月数据

# 绘制第i设备各月非饮料和饮料的销售金额 状态图
def grid_bar(i) -> Bar:
    y_data_1 = 设备_大类_月份_金额[i][0]
    y_data_2 = 设备_大类_月份_金额[i][1]
    y_data_1 = [str(j) for j in y_data_1]
    y_data_2 = [str(j) for j in y_data_2]
    c = (Bar()
         .add_xaxis([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
         .add_yaxis('非饮料', y_data_1)
         .add_yaxis('饮料', y_data_2)
         .set_global_opts(title_opts=opts.TitleOpts(f'{设备[i]}:2017年各月大类商品销售额图'),
                          legend_opts=opts.LegendOpts(orient='vertical', pos_top=30, pos_bottom='40%', is_show=True))
         )
    return c


# 生成所有设备的直方图
bar_name = []
for k in range(num):
    bar_n = "bar_" + str(k)
    bar_name.append(bar_n)
    bar_name[k] = grid_bar(k)

# 显示其中的bar_name[0]
bar_name[0].render('6.html')


# 绘制所有的设备安装大类分类的饼图，上下合成拼成一个图
# 第i设备，各月饮料(j=1)和非饮料(j=0)商品销售额饼图
def Page_pie(i, j) -> Pie:
    if j == 0:
        y_data = y_data_1
        bt = '非饮料'
    if j == 1:
        y_data = y_data_2
        bt = '饮料'
    title = 设备[i] + f':售货机各月【{bt}】商品销售额饼图'  # 标题名称
    html = "../tmp/" + title + "html"

    c = (Pie(init_opts=opts.InitOpts(width='600px', height='400px'))
         .add(bt, [list(z) for z in zip(月份, 设备_大类_月份_金额[i][j])])
         .set_global_opts(title_opts=opts.TitleOpts(title=title, pos_top=0),
                          legend_opts=opts.LegendOpts(orient='vertical', pos_left=5, pos_top=30, is_show=True))
         .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} ({d}%)'))
         )
    return c

# 生成非饮料饼图
pie_0=Page_pie(0,0)
pie_1=Page_pie(1,0)
pie_2=Page_pie(2,0)
pie_3=Page_pie(3,0)
pie_4=Page_pie(4,0)

#生成饮料饼图
pie_01=Page_pie(0,1)
pie_11=Page_pie(1,1)
pie_21=Page_pie(2,1)
pie_31=Page_pie(3,1)
pie_41=Page_pie(4,1)

#先绘制垂直排列顺序多图
page=(Page(page_title='Page绘制平行多图',interval=3,
          layout=Page.DraggablePageLayout).add(bar_name[0],bar_name[1],bar_name[2],bar_name[3],bar_name[4],
                                              pie_0,pie_1,pie_2,pie_3,pie_4,
                                              pie_01,pie_11,pie_21,pie_31,pie_41))
page.render('7.html')

# 如何用图表进行组合展示：Grid并行图，Page顺序多图，Time时间线轮播多图
from pyecharts import options as opts
from pyecharts.charts import Bar, Grid, Line, Scatter


# Grid-上下布局
def grid_vertical() -> Grid:
    bar = (
        Bar()
        .add_xaxis(['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'])
        .add_yaxis('商家A', [5, 20, 36, 10, 75, 90])
        .add_yaxis('商家B', [15, 6, 45, 20, 35, 66])
        .set_global_opts(title_opts=opts.TitleOpts(title='Grid-Bar'))  # 全局配置-标题配置
    )
    line = (
        Line()
        .add_xaxis(['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'])
        .add_yaxis('商家A', [5, 20, 36, 10, 75, 90])
        .add_yaxis('商家B', [15, 6, 45, 20, 35, 66])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="Grid-Line", pos_top="48"),
            legend_opts=opts.LegendOpts(pos_top="48%"),
        )
    )

    grid = (
        Grid()
        .add(bar, grid_opts=opts.GridOpts(pos_bottom="60%"))
        .add(line, grid_opts=opts.GridOpts(pos_top="60%"))
    )
    return grid


grid = grid_vertical()
grid.render('8.html')

# Grid-左右布局
from pyecharts import options as opts
from pyecharts.charts import Bar, Grid, Line, Scatter
def grid_horizontal() -> Grid:
    scatter = (
        Scatter()
        .add_xaxis(['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'])
        .add_yaxis('商家A', [5, 20, 36, 10, 75, 90])
        .add_yaxis('商家B', [15, 6, 45, 20, 35, 66])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="Grid-Scatter"),
            legend_opts=opts.LegendOpts(pos_left="20%"),
        )
    )
    line = (
        Line()
        .add_xaxis(['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'])
        .add_yaxis('商家A', [5, 20, 36, 10, 75, 90])
        .add_yaxis('商家B', [15, 6, 45, 20, 35, 66])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="Grid-Line", pos_right="5%"),
            legend_opts=opts.LegendOpts(pos_right="20%"),
        )
    )
    grid = (
        Grid()
        .add(scatter, grid_opts=opts.GridOpts(pos_right="55%"))
        .add(line, grid_opts=opts.GridOpts(pos_left="55%"))
    )
    return grid
grid_horizontal().render('9.html')
